package com.financing.wap.web.controller.api;


import java.io.IOException;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.financing.wap.service.*;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.financing.wap.common.CommonConstantUtil;
import com.financing.wap.common.ResultMap;
import com.financing.wap.common.CommonConstantUtil.CommonStatus;
import com.financing.wap.dto.DstMemberInfoDTO;
import com.financing.wap.dto.DstUserArticleDTO;
import com.financing.wap.dto.DstUserInfoDTO;
import com.financing.wap.dto.DstUserSubscribeLogDTO;
import com.financing.wap.service.weixin.service.WeixinService;
import com.financing.wap.util.Constants;
import com.financing.wap.util.EmojiFilterUtil;
import com.financing.wap.util.MemcacheCacheHelper;
import com.financing.wap.util.PropertiesUtils;
import com.financing.wap.util.SecureUtil;
import com.financing.wap.util.StringUtil;
import com.financing.wap.web.controller.BaseController;
import com.financing.wap.weixin.service.CoreService;
import com.financing.wap.weixin.util.SignUtil;


/**
 * 微信API
 *
 */
@Controller("weixinController")
@RequestMapping("/wxapi")
public class WeixinController extends BaseController {
	Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	private IDstUserInfoService dstUserInfoService;

    @Autowired
    private IDstUserInfoExpandService dstUserInfoExpandService;

    @Autowired
    private IDstUserArticleService dstUserArticleService;

    @Autowired
    private IDstUserSubscribeLogService dstUserSubscribeLogService;

    @Autowired
    private IDstIntegralRuleService dstIntegralRuleService;


    @Autowired
    private WeixinService weixinJincsServiceImpl;
    
    @Autowired
    private IDstMemberInfoService dstMemberInfoService;
	
	private String MPBACK_URL= PropertiesUtils.getValue("wszl_baseurl")+"/wxapi/weixin/mpbackwszl";
    private String MPBACK_URL_SUBSCRIBE= PropertiesUtils.getValue("wszl_mpback_subscribe");
    private String WSZL_MPBACK_SUBSCRIBE_SENDURL= PropertiesUtils.getValue("wszl_mpback_subscribe_sendurl");


    public static final String WSZL_URL = PropertiesUtils.getValue("wszl_url");
    public static final String WSZL_STATE = PropertiesUtils.getValue("wszl_state");
    public static final String WSZL_SHARE = PropertiesUtils.getValue("wszl_share");
    public static final String WSZL_REDIRECT = PropertiesUtils.getValue("wszl_redirect");
    public static final String WSZL_INDEX = PropertiesUtils.getValue("wszl_index");

    @Autowired
    CoreService coreService;
    
	@RequestMapping(value="/weixin/mp",method=RequestMethod.GET)
	public void editGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
		
		logger.info("In apiweixin MethodGet Begin!");
		 // 微信加密签名  
        String signature = request.getParameter("signature");  
        // 时间戳  
        String timestamp = request.getParameter("timestamp");  
        // 随机数  
        String nonce = request.getParameter("nonce");  
        // 随机字符串  
        String echostr = request.getParameter("echostr");  
  
        PrintWriter out = response.getWriter();  
        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败  
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
            out.print(echostr);  
            logger.info("In apiweixin MethodGet checkSignature SUCCESS!");
        }
        logger.info("In apiweixin MethodGet end!");
        out.close();  
        out = null;  
	}

	@RequestMapping(value="/weixin/mp",method=RequestMethod.POST)
	public void editPost(HttpServletRequest request, HttpServletResponse response) {
	   
	   logger.info("In apiweixin MethodPost Begin!");
	   try {
	      
	      // 将请求、响应的编码均设置为UTF-8（防止中文乱码）  
	       request.setCharacterEncoding("UTF-8");  
	       response.setCharacterEncoding("UTF-8");  

	       // 验证是否是微信入口  
	       boolean checkBoolean = coreService.checkRequest(request);
	       if(!checkBoolean){
	          // 响应消息  
	          PrintWriter out = response.getWriter();  
	          out.print("非法操作！");  
	          out.close();
	          return ;
	       }
	       
	       // 调用核心业务类接收消息、处理消息  
	       final Map<String, String> respMessage = coreService.processRequest(request);  
	         
	       // 响应消息  
	       PrintWriter out = response.getWriter();
	       out.print(respMessage.get("respMessage")); 
	       out.close();
	       
	       //后续处理  - 异步操作
	      new Thread(new Runnable() {
	         public void run() {
	            coreService.processSubsequentRequest(respMessage);  
	         }
	      }).start();
	   
	   } catch (Exception e) {
	      logger.error("In apiweixin MethodPost error!",e);
	   }
	    
	    logger.info("In apiweixin MethodPost end!");
	}
	
    /**
     * 微商授权登录-明授权
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/weixin/wxAuth")
    public void wxAuth(HttpServletRequest request, HttpServletResponse response) {

        if (logger.isInfoEnabled()) {
            logger.info("in wxAuth begin!");
        }
        try {
            String redirect_url=request.getParameter("redirect_url");
            String redirect_url_cache = "";

           if(StringUtils.isNotBlank(redirect_url)){
               logger.info("In wxAuth redirect_url: "+redirect_url);
               redirect_url_cache  = UUID.randomUUID().toString().replace("-", "");
               logger.info("In wxAuth redirect_url_cache: "+redirect_url_cache);

               MemcacheCacheHelper.mcc.set(redirect_url_cache,redirect_url);
           }else{
               logger.info("In wxAuth redirect_url is null!");
               redirect_url_cache = "";
           }

            String url =  weixinJincsServiceImpl.buildAuthorizationUrl(MPBACK_URL,
                    WxConsts.OAuth2Scope.SNSAPI_USERINFO, redirect_url_cache);

           if (logger.isInfoEnabled()) {
               logger.info("================:"+url);
           }
            response.sendRedirect(url);
        } catch (Exception e) {
            logger.error("wxAuth error!", e);
        }
        if (logger.isInfoEnabled()) {
            logger.info("in wxAuth end!");
        }
    }
    /**
     * 微商授权登录-明授权-一次性订阅消息
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/weixin/subscribeMsg")
    @ResponseBody
    public ResultMap subscribemsg(HttpServletRequest request, HttpServletResponse response) {
        ResultMap result = new ResultMap();
        if (logger.isInfoEnabled()) {
            logger.info("in subscribeMsg begin!");
        }
        try {
            String redirect_url = request.getParameter("redirect_url");
            String userOpenid = request.getParameter("userOpenid");
            String articleCode = request.getParameter("articleCode");

            //参数  默认
            if(StringUtils.isBlank(userOpenid) || StringUtils.isBlank(articleCode)){
                result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
                result.setStatus(ResultMap.STATUS.FAILE);
                return result;
            }
            DstUserArticleDTO dstUserArticle=new DstUserArticleDTO();
            dstUserArticle.setUserOpenid(userOpenid);
            dstUserArticle.setDstArticleCode(articleCode);
            dstUserArticle.setDeleteTag(CommonConstantUtil.CommonStatus.DELETE_TAG_NORMAL);
            DstUserArticleDTO userArticle = dstUserArticleService.queryListGetFirst(dstUserArticle);
            //文章不存在
            if(userArticle.getId()==null){
                result.setStatusCode(ResultMap.STATUS_CODE_OPERATE_ERROE);
                result.setStatus(ResultMap.STATUS.FAILE);
                return result;
            }


            String redirect_url_cache = "";
            if(StringUtils.isNotBlank(redirect_url)){
                logger.info("In subscribeMsg redirect_url: "+redirect_url);
                redirect_url_cache  = UUID.randomUUID().toString().replace("-", "");
                logger.info("In subscribeMsg redirect_url_cache: "+redirect_url_cache);

                MemcacheCacheHelper.mcc.set(redirect_url_cache,redirect_url);
            }else{
                logger.info("In subscribeMsg  redirect_url is null!");
                redirect_url_cache = "";
            }

            String url =  weixinJincsServiceImpl.subscribeMsgAuthorizationUrl(MPBACK_URL_SUBSCRIBE, userArticle.getId(), redirect_url_cache);

            if (logger.isInfoEnabled()) {
                logger.info("================:"+url);
            }
            response.sendRedirect(url);
            return null;
        } catch (Exception e) {
            logger.error("subscribeMsg error!", e);
        }
        if (logger.isInfoEnabled()) {
            logger.info("in subscribeMsg end!");
        }
        return null;
    }
    /**
     * 微商授权登录-回调-一次性订阅消息
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/backSubscribeMsg")
    public void backSubscribeMsg(HttpServletRequest request, HttpServletResponse response) {

        if (logger.isInfoEnabled()) {
            logger.info("in backSubscribeMsg begin!");
        }
        try {

            String action = request.getParameter("action");
            String scene = request.getParameter("scene");
            String template_id = request.getParameter("template_id");
            String reserved = request.getParameter("reserved");
            String openid = request.getParameter("openid");

            String redirect_url = null;
            if(StringUtils.isBlank(reserved)){
                logger.info("In backSubscribeMsg reserved is null!");
                reserved = WSZL_INDEX;
            }else{
                logger.info("In backSubscribeMsg redirect_url: "+reserved);
                try {
					redirect_url =  MemcacheCacheHelper.mcc.get(reserved).toString();
					logger.info("In backSubscribeMsg redirect_url_cache: "+redirect_url);
					MemcacheCacheHelper.mcc.delete(reserved);
				} catch (Exception e) {
					logger.info("In backSubscribeMsg reserved is null!");
				}finally{
					reserved = WSZL_INDEX;
				}
            }

            if(org.apache.commons.lang.StringUtils.isBlank(openid) || "cancel".equals(action)){
                logger.info("In backSubscribeMsg user cancel!");
            }else{
                //添加数据库
                DstUserSubscribeLogDTO dstUserSubscribeLog = new DstUserSubscribeLogDTO();
                dstUserSubscribeLog.setScene(scene);
                dstUserSubscribeLog.setUserOpenid(openid);
                dstUserSubscribeLog =   dstUserSubscribeLogService.queryListGetFirst(dstUserSubscribeLog);
                if(dstUserSubscribeLog.getId() == null){
                    DstUserArticleDTO  userArticleDTO= dstUserArticleService.loadById(Integer.valueOf(scene));
                    dstUserSubscribeLog.setScene(scene);
                    dstUserSubscribeLog.setUserArticleCode(userArticleDTO.getDstArticleCode());
                    dstUserSubscribeLog.setUserOpenid(openid);
                    dstUserSubscribeLog.setUserArticleOpenid(userArticleDTO.getUserOpenid());
                    dstUserSubscribeLog.setSendStartus("0");
                    dstUserSubscribeLogService.insert(dstUserSubscribeLog);
                }

            }

            logger.info("In backSubscribeMsg redirect_url: "+redirect_url);
            response.sendRedirect(redirect_url);

        } catch (Exception e) {
            logger.error("backSubscribeMsg error!", e);
        }
        if (logger.isInfoEnabled()) {
            logger.info("in backSubscribeMsg end!");
        }
    }
    /**
     * 微商授权登录-发送-一次性订阅消息
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/weixin/sendSubscribeMsg")
    @ResponseBody
    public ResultMap sendSubscribeMsg(HttpServletRequest request, HttpServletResponse response) {

        ResultMap result = new ResultMap();

        if (logger.isInfoEnabled()) {
            logger.info("in sendSubscribeMsg begin!");
        }

        try {
            String openid = request.getParameter("openid");
            String subscribeId = request.getParameter("subscribeId");

            //参数  默认
            if(StringUtils.isBlank(openid) || StringUtils.isBlank(subscribeId)){
                result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
                result.setStatus(ResultMap.STATUS.FAILE);
                return result;
            }

            //判断订阅是否存在
            DstUserSubscribeLogDTO dstUserSubscribeLogDTO =  dstUserSubscribeLogService.loadById(Integer.valueOf(subscribeId));
            if( dstUserSubscribeLogDTO == null || StringUtils.isBlank(dstUserSubscribeLogDTO.getUserArticleOpenid()) || !openid.equals(dstUserSubscribeLogDTO.getUserArticleOpenid()) || !"0".equals(dstUserSubscribeLogDTO.getSendStartus())){
                result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
                result.setStatus(ResultMap.STATUS.SUCCESS);
                return result;
            }

            //获取用户微信名
            DstUserInfoDTO dstUserInfo = new DstUserInfoDTO();
            dstUserInfo.setUserWechatOpenid(dstUserSubscribeLogDTO.getUserArticleOpenid());
            dstUserInfo = dstUserInfoService.queryListGetFirst(dstUserInfo);

            WxMpSubscribeMessage subscribeMessage = new WxMpSubscribeMessage();
            subscribeMessage.setTitle("邀请通知");
            subscribeMessage.setScene(dstUserSubscribeLogDTO.getScene());
            subscribeMessage.setToUser(dstUserSubscribeLogDTO.getUserOpenid());
            subscribeMessage.setUrl(MessageFormat.format(WSZL_MPBACK_SUBSCRIBE_SENDURL,dstUserSubscribeLogDTO.getUserArticleOpenid()));
            subscribeMessage.setContentValue(StringUtils.isBlank(dstUserInfo.getUserName())?"":dstUserInfo.getUserName()+"正在邀请你添加他为好友,加入与他(她)的聊天。");
            weixinJincsServiceImpl.sendSubscribeMessage(subscribeMessage);

            if (logger.isInfoEnabled()) {
                logger.info("in sendSubscribeMsg subscribeMessage Title:"+subscribeMessage.getTitle());
                logger.info("in sendSubscribeMsg subscribeMessage Scene:"+subscribeMessage.getScene());
                logger.info("in sendSubscribeMsg subscribeMessage ToUser:"+subscribeMessage.getToUser());
                logger.info("in sendSubscribeMsg subscribeMessage Url:"+subscribeMessage.getUrl());
                logger.info("in sendSubscribeMsg subscribeMessage ContentValue:"+subscribeMessage.getContentValue());
            }
            //修改发送状态
            dstUserSubscribeLogDTO.setSendStartus("1");
            dstUserSubscribeLogService.update(dstUserSubscribeLogDTO);

            result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
            result.setStatus(ResultMap.STATUS.SUCCESS);


        } catch (Exception e) {
            logger.error("sendSubscribeMsg error!", e);

            result.setStatus(ResultMap.STATUS.ERROR);
            result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
        }
        if (logger.isInfoEnabled()) {
            logger.info("in sendSubscribeMsg end!");
        }

        return  result;
    }

    private String getToken(HttpServletRequest request) throws Exception {
        Cookie[] cookies =  request.getCookies();
        String token="";
        for(Cookie tokenCookie : cookies ){
            log.debug("!tokenCookie name"+tokenCookie.getName());
            if(Constants._TOKEN.equals(tokenCookie.getName())){
                tokenCookie.setMaxAge(60*60*24);
                tokenCookie.setPath("/");
                token = tokenCookie.getValue();
                log.info("!token:"+token);
                if(StringUtils.isBlank(token)){
                    continue;
                }
                int k = 4-(token.length()%4);
                if(k!=4){
                    for(int i = 0;i< k;i++){
                        token = token +"=";
                    }
                }
                break;
            }
        }
        token = SecureUtil.decrypt(token);
        return token;
    }

    /**
     * 微信授权登录-回调
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/weixin/mpbackwszl")
    public  void mpbackwszl(HttpServletRequest request, HttpServletResponse response) {

        if (logger.isInfoEnabled()) {
            logger.info("In mpbackwszl begin!");
        }
        try {
            String code = request.getParameter("code");
            if (logger.isInfoEnabled()) {
                logger.info("In mpbackwszl code: "+code);
            }

            String state = request.getParameter("state");
            String redirect_url = null;

            if(StringUtils.isBlank(state)){
                logger.info("In mpbackwszl state is null!");
                redirect_url = WSZL_INDEX;
            }else{
                logger.info("In mpbackwszl redirect_url: "+state);
                redirect_url =  MemcacheCacheHelper.mcc.get(state).toString();
                logger.info("In mpbackwszl redirect_url_cache: "+redirect_url);
                MemcacheCacheHelper.mcc.delete(state);
            }

            //获取微信用户信息
            WxMpUser wxMpUser = weixinJincsServiceImpl.getUserInfo(code);

            logger.info("In mpbackwszl wxMpUser: "+wxMpUser.toString());
            wxMpUser.setNickname(EmojiFilterUtil.filterEmoji(wxMpUser.getNickname()));
            //微信用户信息 存入数据库
            weixinJincsServiceImpl.saveMpUserToLocal(wxMpUser);
            String token = wxMpUser.getOpenId();
            
			DstMemberInfoDTO dstMemberInfo=new DstMemberInfoDTO();
			dstMemberInfo.setDeleteTag(CommonStatus.DELETE_TAG_NORMAL);
			dstMemberInfo.setUserOpenid(token);
			DstMemberInfoDTO member = dstMemberInfoService.queryListGetFirst(dstMemberInfo);
			if(member.getId()==null){
				dstMemberInfoService.createMember(token);
			}

			//会员体验获取 -注入
            dstIntegralRuleService.executeAuth(token);
            
			try {
				token = SecureUtil.encrypt(token).replaceAll("=", "");
				Cookie cookie = new Cookie(Constants._TOKEN, token);
				cookie.setMaxAge(60*60*24);
				cookie.setPath("/");
				response.addCookie(cookie);
			} catch (Exception e) {
				log.error("mobile pt create token error!",e);
			}

            if(redirect_url.indexOf("?") >0){
                redirect_url = redirect_url.replaceFirst("\\?","?openId="+wxMpUser.getOpenId()+"&");
            }else{
                redirect_url = redirect_url + "?openId="+wxMpUser.getOpenId();
            }

            logger.info("In mpbackwszl redirect_url: "+redirect_url);

            response.sendRedirect(redirect_url);
        
        } catch (Exception e) {
            logger.error("In mpbackwszl error!", e);
        }
        if (logger.isInfoEnabled()) {
            logger.info("In mpbackwszl end!");
        }
    }
    
    
    /***
	 *wx 登录状态
	 * @param request
	 * @return
	 */
	@RequestMapping("/weixin/loginStatus")
	@ResponseBody
	public ResultMap loginStatus(HttpServletRequest request){
		ResultMap result = new ResultMap();
		try{
			logger.info("query loginStatus begin .......");
			String token = getToken(request);
			if(!StringUtil.isNullOrEmptyStr(token)){
				result.setAttribute("loginStatus",true);
			}else{
				result.setAttribute("loginStatus",false);
			}
			result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
			result.setStatus(ResultMap.STATUS.SUCCESS);
			logger.info("query loginStatus list end .......");
		}catch(Exception e){
			result.setAttribute("loginStatus",false);
			result.setStatus(ResultMap.STATUS.ERROR);
			result.setStatusCode(ResultMap.LOGIN_NOLOGIN_ERROR);
		}
		return result;
	}
	
}
